package com.qys.livesMall.shop.service.impl;

import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qys.livesMall.app.user.model.entity.H2AppUser;
import com.qys.livesMall.app.user.service.IH2AppUserService;
import com.qys.livesMall.common.exception.QysException;
import com.qys.livesMall.common.utils.ParamCheckUtil;
import com.qys.livesMall.finance.enums.AccountBusinessTypeEnum;
import com.qys.livesMall.finance.model.dto.FinancePayDTO;
import com.qys.livesMall.finance.service.FinanceBusinessService;
import com.qys.livesMall.finance.util.BusinessNoUtil;
import com.qys.livesMall.framework.utils.SecurityUtils;
import com.qys.livesMall.shop.enums.ShopMessageEnum;
import com.qys.livesMall.shop.mapper.H2DataPackageMapper;
import com.qys.livesMall.shop.mapper.H2DataPackageShopMapper;
import com.qys.livesMall.shop.mapper.H2ShopBaseMapper;
import com.qys.livesMall.shop.mapper.ShopDataDetailMapper;
import com.qys.livesMall.shop.modal.dto.*;
import com.qys.livesMall.shop.modal.entity.*;
import com.qys.livesMall.shop.service.*;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;

/**
 * 流量包表(H2DataPackage)表服务实现类
 *
 * @author makejava
 * @since 2023-06-20 13:43:49
 */
@Service("h2DataPackageService")
public class H2DataPackageServiceImpl extends ServiceImpl<H2DataPackageMapper, H2DataPackage> implements H2DataPackageService {

    @Resource
    private H2ShopBaseMapper shopBaseMapper;
    @Resource
    private H2DataPackageMapper dataPackageMapper;
    @Resource
    private H2DataPackageShopMapper dataPackageShopMapper;
    @Resource
    private H2ShopBalanceService shopBalanceService;
    @Resource
    private SysShopDataConsumeService shopDataConsumeService;
    @Resource
    private ShopDataStatisticsService shopDataStatisticsService;
    @Resource
    private FinanceBusinessService financeBusinessService;
    @Resource
    private ShopDataDetailMapper shopDataDetailMapper;

    @Autowired
    private IH2AppUserService userService;

    @Override
    public String buyDataPackage(BuyDataPackageDTO buyDataPackageDTO) {
        H2ShopBase h2ShopBase = shopBaseMapper.selectById(Long.parseLong(buyDataPackageDTO.getShopId()));
        if(null == h2ShopBase){
            throw new QysException(ShopMessageEnum.SHOP_NOT_EXIST);
        }

        H2DataPackage aPackage = dataPackageMapper.selectById(Long.parseLong(buyDataPackageDTO.getPackageId()));
        if(null == aPackage){
            throw new QysException(ShopMessageEnum.DATA_PACKAGE_NOT_EXIST);
        }

        H2DataPackageShop packageShop = new H2DataPackageShop();
        packageShop.setAmount(aPackage.getPackagePrice());
        packageShop.setPackageId(Long.parseLong(buyDataPackageDTO.getPackageId()));
        packageShop.setShopId(Long.parseLong(buyDataPackageDTO.getShopId()));
        dataPackageShopMapper.insert(packageShop);
        return String.valueOf(packageShop.getOrderId());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public synchronized void payDataPackage(PayDataPackageDTO dto) {

        //1.判断订单是否存在和状态
        H2DataPackageShop order = dataPackageShopMapper.selectById(dto.getOrderId());
        if(null == order){
            throw new QysException(ShopMessageEnum.SHOP_NOT_FIND_ORDER);
        }
        if(1 == order.getOrderStatus()){
            throw new QysException(ShopMessageEnum.SHOP_ORDER_STATUS_EXCEPTION);
        }

        //2.判断密码是否正确
        H2ShopBase shop = shopBaseMapper.selectById(order.getShopId());
//        if (StringUtils.isBlank(user.getPassword())) {
//            throw new QysException(ShopMessageEnum.SHOP_PASSWORD_IS_NULL);
//        }
//        if (!SecurityUtils.matchesPassword(dto.getPassword(), user.getPassword())) {
//            throw new QysException(ShopMessageEnum.SHOP_PASSWORD_IS_ERROR);
//        }
        userService.checkUserPayPassword(SecurityUtils.getUserId().toString(),dto.getPassword());

        //3.进行扣款
        FinancePayDTO financePayDTO = new FinancePayDTO();
        financePayDTO.setUserId(SecurityUtils.getUserId());
        financePayDTO.setShopId(order.getShopId());
        financePayDTO.setAmountIncurred(order.getAmount());
        financePayDTO.setBusinessType(AccountBusinessTypeEnum.SHOP_DATA_PACKAGE);
        financePayDTO.setBusinessNo(BusinessNoUtil.get(AccountBusinessTypeEnum.SHOP_DATA_PACKAGE));
        financeBusinessService.pay(financePayDTO);

        if(!financePayDTO.getSuccess()){
            throw new QysException(financePayDTO.getMessage());
        }

        //4.更改订单状态
        H2DataPackageShop h2DataPackageShop = new H2DataPackageShop();
        h2DataPackageShop.setOrderId(order.getOrderId());
        h2DataPackageShop.setOrderStatus(1);
        h2DataPackageShop.setPayTime(LocalDateTime.now());
        dataPackageShopMapper.updateById(h2DataPackageShop);

        //5.更新流量消耗表剩余流量
        Wrapper<SysShopDataConsume> wrapper = Wrappers.<SysShopDataConsume>lambdaQuery().eq(SysShopDataConsume::getShopId, shop.getId());
        SysShopDataConsume consume = shopDataConsumeService.getOne(wrapper);

        H2DataPackage aPackage = dataPackageMapper.selectById(order.getPackageId());
        Integer giftData = aPackage.getGiftData();
        int payData = aPackage.getPackageContent() + ( null == giftData ? 0 : giftData );

        Integer type = aPackage.getDataType();

        SysShopDataConsume newConsume = new SysShopDataConsume();
        if(null == consume){
            newConsume.setShopId(order.getShopId());
            newConsume.setResidue((long) payData);
            shopDataConsumeService.save(newConsume);
        } else {
            newConsume.setId(consume.getId());
            newConsume.setResidue(consume.getResidue() + payData);
            shopDataConsumeService.updateById(newConsume);
        }

        //6.更新店铺流量剩余表
        Wrapper<ShopDataStatistics> shopDataStatisticsWrapper = Wrappers.<ShopDataStatistics>lambdaQuery().eq(ShopDataStatistics::getShopId, shop.getId());
        ShopDataStatistics shopDataStatistics = shopDataStatisticsService.getOne(shopDataStatisticsWrapper);

        ShopDataStatistics editStatistics = new ShopDataStatistics();
        editStatistics.setLastBuyTime(LocalDateTime.now());
        if(null == shopDataStatistics){
            editStatistics.setShopId(order.getShopId());
            editStatistics.setShopName(shop.getShopName());
            editStatistics.setTotalQuantity(payData);
            editStatistics.setResidue(payData);
            if(1 == type){
                editStatistics.setInstation(aPackage.getDeliveryHomepage());
                editStatistics.setOutside(aPackage.getOffStationPlatform());
                editStatistics.setOverseas(aPackage.getOverseasPromotion());
            }
            shopDataStatisticsService.save(editStatistics);
        } else {
            editStatistics.setId(shopDataStatistics.getId());
            editStatistics.setTotalQuantity(shopDataStatistics.getTotalQuantity() + payData);
            editStatistics.setResidue(shopDataStatistics.getResidue() + payData);
            if(1 == type){
                editStatistics.setInstation(shopDataStatistics.getInstation() + aPackage.getDeliveryHomepage());
                editStatistics.setOutside(shopDataStatistics.getOutside() + aPackage.getOffStationPlatform());
                editStatistics.setOverseas(shopDataStatistics.getOverseas() + aPackage.getOverseasPromotion());
            }
            shopDataStatisticsService.updateById(editStatistics);
        }

        //7.保存流量明细表
        ShopDataDetail dataDetail = new ShopDataDetail();
        dataDetail.setShopId(order.getShopId());
        dataDetail.setTransactionType("1");
        dataDetail.setPacketId(order.getPackageId());
        dataDetail.setVolume(payData);
        dataDetail.setSurplus(consume == null ? payData : (int) (consume.getResidue() + payData));
        shopDataDetailMapper.insert(dataDetail);
    }

    @Override
    public List<QueryAddressVO> queryAddress(QueryAddressDTO dto) {
        Locale locale = LocaleContextHolder.getLocale();
        boolean en = locale.toLanguageTag().contains("en");

        ParamCheckUtil.checkField(dto,false,"level");

        HashMap<String, Object> param = new HashMap<>(4);
        if(StringUtils.isNotBlank(dto.getAreaId())){
            param.put("id", Integer.valueOf(dto.getAreaId()));
            param.put("len", dto.getAreaId().length());
        }
        param.put("level", Integer.valueOf(dto.getLevel()));
        param.put("langType", en ? "en_US" : "zh_CN");
        return dataPackageMapper.queryAddress(param);
    }

    @Override
    public List<Tree<Integer>> allAddress() {
        Locale locale = LocaleContextHolder.getLocale();
        boolean en = locale.toLanguageTag().contains("en");
        List<AddressVO> addressVOS = dataPackageMapper.queryAddressByNationCode(en ? "en_US" : "zh_CN");

        return TreeUtil.build(addressVOS, null, new TreeNodeConfig(),
                (a, e) -> {
                    e.setId(a.getId());
                    e.setParentId(a.getParentId());
                    e.setName(a.getAreaName());
                });
    }

}

